﻿using CRedis.Client;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CRedis.Third.Redis;
using System.Diagnostics;

namespace RedisClientTest
{
    public static class TaskCreator
    {
        public static void Run()
        {
            //ICacheProvider provider = CacheFactory.GetPorvider("MyTest");            

            ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
            #region tasks
            string tasks = @"2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12
2014-12-12 10:09:12";
            #endregion

            IDatabase db = redis.GetDatabase();
            //ParallelLoopResult[] pushResult = new ParallelLoopResult[2000];
            var sw = Stopwatch.StartNew();
            Task[] pushTasks = new Task[2000];
            for (int i = 0; i < 2000; i++)
            {
                pushTasks[i] = Push(db, i, tasks);
            }
            Task.WaitAll(pushTasks);
            long pushElapsed = sw.ElapsedMilliseconds;
            //sw.Stop();
            //Console.WriteLine("press any key to start pop");
            //Console.ReadLine();
            //sw.Start();

            Task[] popTasks = new Task[2000];
            for (int i = 0; i < 2000; i++)
            {
               popTasks[i] =Pop(db, i);
            }
            Task.WaitAll(popTasks);
            sw.Stop();
            long popElapsed = sw.ElapsedMilliseconds - pushElapsed;
            Console.WriteLine(string.Format("push takes {0} ms", pushElapsed));
            Console.WriteLine(string.Format("pop takes {0} ms", popElapsed));
            
        }

        private static async Task Pop(IDatabase db, int i)
        {
            string key = "TaskList_" + i;
            string hashKey = "TaskHash_" + i;
            string value = string.Empty;
            int j = 0;

            //var fields = db.ListRangeAsync(key, 0, -1).Result;
            Task[] tasks = new Task[500];
            while (j < 500)
            {
                try
                {

                    //string hashField = "SH_SY_" + j;
                    tasks[j] = db.ListLeftPopAsync(key);                    
                    //value = db.HashGet(hashKey, hashField);
                    //Console.WriteLine("pop:" + value);
                    j++;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
            Task.WaitAll(tasks);
            var values = await db.HashValuesAsync(hashKey);
            Console.WriteLine("pop: " + tasks.Length + " fields from " + key);
            Console.WriteLine("retrieve: " + values.Length +" entries from " + hashKey);
           
        }


        private static void Pop(ICacheProvider db, int i)
        {
            try
            {
                string key = "TaskList_" + i;
                string hashKey = "TaskHash_" + i;
                string value = string.Empty;
                
                List<string> itemList = db.GetRangeFromList(key, 0, 499);
                Console.WriteLine("pop:" + key);
                var values = db.GetValuesFromHash(hashKey, itemList.ToArray());
                Console.WriteLine("pop:" + hashKey);
                //Dictionary<string, string> entries = db.GetAllEntriesFromHash(hashKey);

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            //while (value != RedisValue.Null)//(length <= 500)//
            //{
            //    try
            //    {
            //        value = db.ListLeftPop(key);
            //        Console.WriteLine(value);
            //        if (value != RedisValue.Null)
            //        {
            //            string[] valueArray = value.Split(':');
            //            hashKey = valueArray[0];
            //            string hashField = valueArray[1];
            //            db.HashGet(hashKey, hashField);
            //        }
            //    }
            //    catch (Exception ex)
            //    {
            //        Console.WriteLine(ex);
            //    }
            //}
        }
        private static void Push(ICacheProvider db, int i, string tasks)
        {
            try
            {
                

                string key = "TaskList_" + i;
                string hashKey = "TaskHash_" + i;
                //long length = 1;
                int j = 0;
                //using (var pipeline = ((RedisClient)db).CreatePipeline())
                //{
                List<string> listValues = new List<string>();
                System.Collections.Generic.Dictionary<string, string> hashValues = new Dictionary<string, string>();
                //var pipeline = db.GetPipeline();
                while (j < 500)
                {
                    string hashField = "SH_SY_" + j;
                    hashValues.Add(hashField, tasks);
                    listValues.Add(hashField);
                    //pipeline.((c) =>
                    //{
                    //    c.SetEntryInHash(hashKey, j + string.Empty, tasks);
                    //});

                    //pipeline.QueueCommand((c) =>
                    //{
                    //    c.PushItemToList(key, );
                    //});
                    j++;
                }
                //pipeline.Flush();
                //}
                Console.WriteLine("push");
                db.SetRangeInHash(hashKey, hashValues);
                Console.WriteLine(hashKey);
                db.AddRangeToList(key, listValues);
                Console.WriteLine(key);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        private static async Task Push(IDatabase db, int i, string tasks)
        {
            string key = "TaskList_" + i;
            string hashKey = "TaskHash_" + i;
            //long length = 1;
            int j = 0;
            Task[] taskArray = new Task[1000];
            while (j < 500)
            {
                try
                {
                    string hashField = "SH_SY_" + j;
                    taskArray[j] = db.HashSetAsync(hashKey, hashField, tasks);//, When.Always, CommandFlags.FireAndForget);
                    taskArray[j+500] = db.ListRightPushAsync(key, hashField);//, When.Always, CommandFlags.FireAndForget);//
                    j++;
                    //Console.WriteLine("push:" + hashField);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
            
            await Task.WhenAll(taskArray);
            Console.WriteLine("push:" + hashKey);
        }

    }
}
